package com.cms.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cms.entity.Nav;
import com.cms.mapper.NavMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cms.utils.DbUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 导航表 服务实现类
 * </p>
 *
 * @author songfayuan
 * @since 2021-11-12
 */
@Service
public class NavService extends ServiceImpl<NavMapper, Nav> {


    /**
     * 根据URL目录获取导航
     * @return	导航
     */
    public Nav findByUrl(String url, Integer siteId){
        QueryWrapper<Nav> queryWrapper = new QueryWrapper();
        queryWrapper.eq("url",url);
        queryWrapper.eq("siteId",siteId);
        return baseMapper.selectOne(queryWrapper);
    }


    /**
     * 查找顶级导航
     *
     * @param start
     *            起始位置
     * @param count
     *            数量
     * @return 顶级导航
     */
    public List<Nav> findRoots(Integer start, Integer count,Integer siteId){
        QueryWrapper<Nav> queryWrapper = new QueryWrapper();
        queryWrapper.isNull("parentId");
        queryWrapper.eq("siteId",siteId);
        queryWrapper.orderByDesc("sort");
        String limit = DbUtils.getCountSql(start,count);
        if(StringUtils.isNotBlank(limit)){
            queryWrapper.last(limit);
        }
        return baseMapper.selectList(queryWrapper);

    }


    /**
     * 查找上级导航
     *
     * @param id
     *            导航Id
     * @param recursive
     *            是否递归
     * @param start
     *            起始位置
     * @param count
     *            数量
     * @return 上级导航
     */
    public List<Nav> findParents(Integer id,Boolean recursive,Integer start, Integer count,Integer siteId){
        Nav nav = baseMapper.selectById(id);
        if(id == null || nav.getParentId() == null){
            return Collections.emptyList();
        }
        QueryWrapper<Nav> queryWrapper = new QueryWrapper();
        queryWrapper.eq("siteId",siteId);
        if(recursive){
            queryWrapper.in("id",nav.getParentIds());
            queryWrapper.orderByAsc("grade");
            String limit = DbUtils.getCountSql(start,count);
            if(StringUtils.isNotBlank(limit)){
                queryWrapper.last(limit);
            }
            return baseMapper.selectList(queryWrapper);
        }else{
            queryWrapper.eq("id",nav.getParentId());
            return baseMapper.selectList(queryWrapper);
        }
    }


    /**
     * 查找下级导航
     *
     * @param id
     *            导航Id
     * @param recursive
     *            是否递归
     * @param start
     *            起始位置
     * @param count
     *            数量
     * @return 下级导航
     */
    public List<Nav> findChildren(Integer id, Boolean recursive, Integer start, Integer count, Integer siteId){
        QueryWrapper<Nav> queryWrapper = new QueryWrapper();
        queryWrapper.eq("siteId",siteId);
        if(recursive){
            queryWrapper.orderByAsc("grade").orderByDesc("sort");
            String limit = DbUtils.getCountSql(start,count);
            if(StringUtils.isNotBlank(limit)){
                queryWrapper.last(limit);
            }
            List<Nav> navs;
            if(id!=null){
                queryWrapper.like("treePath",","+id+",");
                navs = baseMapper.selectList(queryWrapper);
            }else{
                navs = baseMapper.selectList(queryWrapper);
            }
            sort(navs);
            return navs;
        }else{
            queryWrapper.eq("parentId",id);
            queryWrapper.orderByDesc("sort");
            return baseMapper.selectList(queryWrapper);
        }
    }

    /**
     * 查找导航树
     *
     * @return 导航树
     */
    public List<Nav> findTree(Integer siteId){
        return findChildren(null,true,null,null,siteId);
    }

    /**
     * 排序导航
     *
     * @param navs
     *            分类
     */
    private void sort(List<Nav> navs) {
        if(navs == null || navs.size()==0) {
            return;
        }
        final Map<Integer, Integer> sortMap = new HashMap<Integer, Integer>();
        for (Nav nav : navs) {
            sortMap.put(nav.getId(), nav.getSort());
        }
        Collections.sort(navs, new Comparator<Nav>() {
            @Override
            public int compare(Nav nav1, Nav nav2) {
                Integer[] ids1 = (Integer[]) ArrayUtils.add(nav1.getParentIds(), nav1.getId());
                Integer[] ids2 = (Integer[]) ArrayUtils.add(nav2.getParentIds(), nav2.getId());
                Iterator<Integer> iterator1 = Arrays.asList(ids1).iterator();
                Iterator<Integer> iterator2 = Arrays.asList(ids2).iterator();
                CompareToBuilder compareToBuilder = new CompareToBuilder();
                while (iterator1.hasNext() && iterator2.hasNext()) {
                    Integer id1 = iterator1.next();
                    Integer id2 = iterator2.next();
                    Integer sort1 = sortMap.get(id1);
                    Integer sort2 = sortMap.get(id2);
                    compareToBuilder.append(sort2,sort1).append(id1, id2);
                    if (!iterator1.hasNext() || !iterator2.hasNext()) {
                        compareToBuilder.append(nav1.getGrade(), nav2.getGrade());
                    }
                }
                return compareToBuilder.toComparison();
            }
        });
    }

}
